package repository

import (
	"context"
	"furniture-server-gin/api/pkg/domain/permission"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
)

type permissionRepository struct {
	collection *mongo.Collection
}

// NewPermissionRepository 创建权限仓库实例
func NewPermissionRepository(database *mongo.Database) permission.Repository {
	return &permissionRepository{
		collection: database.Collection("permissions"),
	}
}

// Create 创建权限
func (r *permissionRepository) Create(permission *permission.Permission) error {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	// 如果ID为空，生成新的ObjectID
	if permission.ID == "" {
		permission.ID = primitive.NewObjectID().Hex()
	}

	_, err := r.collection.InsertOne(ctx, permission)
	return err
}

// Update 更新权限
func (r *permissionRepository) Update(permission *permission.Permission) error {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	objectID, err := primitive.ObjectIDFromHex(permission.ID)
	if err != nil {
		return err
	}

	filter := bson.M{"_id": objectID}
	update := bson.M{"$set": permission}

	_, err = r.collection.UpdateOne(ctx, filter, update)
	return err
}

// Delete 删除权限
func (r *permissionRepository) Delete(id string) error {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	objectID, err := primitive.ObjectIDFromHex(id)
	if err != nil {
		return err
	}

	filter := bson.M{"_id": objectID}
	_, err = r.collection.DeleteOne(ctx, filter)
	return err
}

// FindByID 根据ID查找权限
func (r *permissionRepository) FindByID(id string) (*permission.Permission, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	objectID, err := primitive.ObjectIDFromHex(id)
	if err != nil {
		return nil, err
	}

	filter := bson.M{"_id": objectID}
	var permission permission.Permission
	err = r.collection.FindOne(ctx, filter).Decode(&permission)
	if err != nil {
		if err == mongo.ErrNoDocuments {
			return nil, nil
		}
		return nil, err
	}

	return &permission, nil
}

// FindByName 根据名称查找权限
func (r *permissionRepository) FindByName(name string) (*permission.Permission, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	filter := bson.M{"name": name}
	var permission permission.Permission
	err := r.collection.FindOne(ctx, filter).Decode(&permission)
	if err != nil {
		if err == mongo.ErrNoDocuments {
			return nil, nil
		}
		return nil, err
	}

	return &permission, nil
}

// FindAll 查找所有权限
func (r *permissionRepository) FindAll() ([]*permission.Permission, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	cursor, err := r.collection.Find(ctx, bson.M{})
	if err != nil {
		return nil, err
	}
	defer cursor.Close(ctx)

	var permissions []*permission.Permission
	for cursor.Next(ctx) {
		var permission permission.Permission
		if err := cursor.Decode(&permission); err != nil {
			return nil, err
		}
		permissions = append(permissions, &permission)
	}

	if err := cursor.Err(); err != nil {
		return nil, err
	}

	return permissions, nil
}
